﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Workflow.Application.DTOs.Input;
using Workflow.Application.IService;
using Workflow.Application.Service;
using Workflow.Domain.Enums;
using Workflow.Domain.Models;
using Workflow.Infrastructure.IRepository;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using Yitter.IdGenerator;

namespace Workflow.Application.Step
{
    public class AuditStep : StepBodyAsync
    {
        private long auditUserId;
        private readonly IBaseRepository<WorkflowInstanceModel> instanceBase;
        private readonly IBaseRepository<AuditModel> auditBase;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="instanceBase"></param>
        /// <param name="auditBase"></param>
        public AuditStep(IBaseRepository<WorkflowInstanceModel> instanceBase, IBaseRepository<AuditModel> auditBase)
        {
            this.instanceBase = instanceBase;
            this.auditBase = auditBase;
        }

        public override async Task<ExecutionResult> RunAsync(IStepExecutionContext context)
        {
            try
            {
                auditUserId = Convert.ToInt64(context.Item);
                if (!context.ExecutionPointer.EventPublished)
                {

                    //添加审批信息
                    AuditModel audit = new AuditModel()
                    {
                        Id = YitIdHelper.NextId(),
                        AuditUserId = auditUserId,
                        //AuditUserName= AuditUserName,
                        WorkflowId = context.Workflow.Id,
                        StepId = context.Step.ExternalId,
                        StepName = context.Step.Name,
                        StatuEnum = WorkFlowAuditStatuEnum.UnAudited,
                    };
                    //分布式事务
                    using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                    {
                        try
                        {
                            await auditBase.AddRange(audit);
                            tran.Complete();
                        }
                        catch (Exception)
                        {

                            throw;
                        }
                    }
                    return ExecutionResult.WaitForEvent(audit.Id.ToString(), context.Workflow.Id, DateTime.Now);
                }
                // 获取审批意见

                #region 激活子节点(审批，驳回)
                var eventData = context.ExecutionPointer.EventData as AuditInput;
                //如果持久化数据为null
                if (context.PersistenceData == null)
                {
                    // 将WorkflowAuditInput事件数据持久化到所有子节点，
                    // 此处list有n条就会按照子 节点*n 构建下一步节点
                    var result = ExecutionResult.Branch(new List<object> { eventData }, new ControlPersistenceData { ChildrenActive = true });
                    // GetDescription(): 是个枚举扩展方法，获取Desription特性的作用。
                    result.OutcomeValue = eventData.OperateTypeEnum;
                    return result;
                }
                //激活子节点
                if ((context.PersistenceData is ControlPersistenceData data) && (data.ChildrenActive))
                {
                    if (context.Workflow.IsBranchComplete(context.ExecutionPointer.Id))
                        return ExecutionResult.Next();
                    else
                    {
                        var result = ExecutionResult.Persist(context.PersistenceData);
                        result.OutcomeValue = eventData.OperateTypeEnum;
                        return result;
                    }
                }
                #endregion
                // 流转到下一个节点
                return ExecutionResult.Next();
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}
